package com.cy.security;

//import java.util.regex.Matcher;
//import java.util.regex.Pattern;

import com.alibaba.fastjson.JSONObject;
import com.cy.model.BrewedLog;
import com.cy.utils.factors.Factors;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Main {

	public static void main(String[] args) {
//		Date d = parseOS("05F9DD50");
		System.out.println(Encryption.getHashCode(8, 4));
		/*double [] vP = {20,40,100,80};
		double [] vTo = {45.5,62,85,82};
		double [] vFs = {5604.00,4520.56,4919.07,4607.73};
//		pdList:[20,40,100,80]-fdList:["5604.00","4520.56","4919.07","4607.73"]-tempList:[45.5,62,85,82]
		*//*
		double [] vP = { 10,30,90,60};
		double [] vTo = {41,53,82,75};
		double [] vFs = {4919.07,4732.27,4763.40,4498.77};*//*
//		pdList:[10,30,90,60]-fdList:["4919.07","4732.27","4763.40","4498.77"]-tempList:[41,53,82,75]
//		pdList:[20,40,100,80]-fdList:["5604.00","4520.56","4919.07","4607.73"]-tempList:[45.5,62,85,82]

		int [] m = Factors.calcDynamicABCDModel(vP, vFs, vTo);

		if(m!=null){
			System.out.println("Model is:\nA:"+m[0]+"\t"+Factors.toHex2Bytes(m[0])+"\nB:"+m[1]+"\t"+Factors.toHex2Bytes(m[1])+"\nC:"+m[2]+"\t"+Factors.toHex2Bytes(m[2])+"\nD:"+m[3]+"\t"+Factors.toHex2Bytes(m[3])+"\nS:"+m[4]+"\t"+Factors.toHex2Bytes(m[4]));
		}*/

		/*double [] vt = {129*1.0, -106*1.0, 0}; // {t0, t1, t2}
		double [] vd = {(int)-vt[0]*1E3/vt[1], (int)1E5/vt[1], 0}; // {d0, d1, d2}
		double [] vP = {10,30,95,60};
		double [] vFs = {4670,4670,4686.1,4311.97};
		double [] vDd = {895, 710, 345, 440};
		double [] vDe = {1028, 1028, 1028, 1028};
		int [] m = Factors.calcDynamicXYZModel(vP, vFs, vDd, vDe);
		System.out.println(m[0]+"\t"+m[1]+"\t"+m[2]+"\t"+m[3]);
		int To=90;
		int Td = To*(1+To*20/10000);
		int Te = 20;
		int Fs = 5000;
		int G = (int) ((Td-Te)*Fs / 1E2);
		int P = (int) (m[0]*(G*G/1E3+12*G/10)/1E3+m[1]);
		for(int i=0; i< m[2]; i++)	P = P*10;
		P/=1E3;
		System.out.println("P="+P);*/

		/*Encryption enc = new Encryption();
		enc.setTn("81");
		enc.setRaw("0001");
		enc.setKey("0000");
		enc.setCs(Encryption.getCs(enc.getRaw(), enc.getKey()));
		String os = Encryption.getDateOs(2016,2,22,17,0,0);
		enc.setOs(os);
		enc.setDn("67245152535188700674FF52");

		System.out.println("==========================");
		System.out.println("[ENCRYPTION]\nraw:"+enc.getRaw()+",\tkey:"+enc.getKey()+",\tcs:"+enc.getCs()+",\tos:"+enc.getOs()+",\tdn:"+enc.getDn()+",\ttn:"+enc.getTn());
		enc = Encryption.encrypt(enc);
		String code = enc.getCode();
		System.out.println("code:"+code);
		System.out.println("==========================");
		Encryption dec = new Encryption();
		dec.setDn("67245152535188700674FF52");
		dec.setKey("0000");
		dec.setCode(code);
		dec.setTn("81");
		dec = Encryption.decrypt(dec);
		System.out.println("[DENCRYPTION]\nraw:"+dec.getRaw()+",\tkey:"+dec.getKey()+",\tcs:"+dec.getCs()+",\tos:"+dec.getOs()+",\tdn:"+dec.getDn()+",\ttn:"+dec.getTn());
		System.out.println("==========================");
		System.out.println("[VALIDATION]\nenc_raw:"+enc.getRaw()+",\tenc_key:"+enc.getKey()+",\tenc_cs:"+enc.getCs());
		System.out.println("dec_raw:"+dec.getRaw()+",\tdec_key:"+dec.getKey()+",\tdec_cs:"+dec.getCs());*/

		/*int count = parseDS("049ADEF501540128002C000000000000;049ADEFF01540128002C000000000000;049ADF0701540128002C000000000000;",1,1);
		System.out.println("count="+count);*/
		/*Encryption enc = new Encryption();{6BC73C09106BC404D9A6B5,577A474EB860}
		enc.setTn("04");
		enc.setRaw("18B5");
		enc.setKey("0A0B");
		enc.setCs(Encryption.getCs(enc.getRaw(), enc.getKey()));
		enc.setOs("53ADA0DF");
		enc.setDn("77665544332211");

		System.out.println("==========================");
		System.out.println("[ENCRYPTION]\nraw:"+enc.getRaw()+", key:"+enc.getKey()+", cs:"+enc.getCs()+", os:"+enc.getOs()+", dn:"+enc.getDn()+", tn:"+enc.getTn());
		enc = Encryption.encrypt(enc);
		String code = enc.getCode();
		System.out.println("code:"+code);
		System.out.println("==========================");
		Encryption dec = new Encryption();
		dec.setDn("77665544332211");
		dec.setKey("0A0B");
		dec.setCode(code);
		System.out.println("[ENCRYPTION]\nmark:"+dec.getMark()+", key:"+dec.getKey()+", cs:"+dec.getCs()+", os:"+dec.getOs()+", dn:"+dec.getDn()+", tn:"+dec.getTn());
		dec.setRaw("");
		dec = Encryption.decrypt(dec);
		System.out.println("raw:"+dec.getRaw());
		System.out.println("==========================");
		System.out.println("[VALIDATION]\nraw:"+enc.getRaw()+", key:"+enc.getKey()+", cs:"+enc.getCs());
		String cs_rec = Encryption.getCs(dec.getRaw(), dec.getKey());
		System.out.println("cs_rec:"+cs_rec);*/
		/*double [] doubleP = {90,70,70,50,30};
		double [] doubleF = {80,80,100,90,100};
		double [] doubleT = {86.20,80.20,68.50,63.60,50.40};

		int [] modelParam = Factors.calcDynamicABCModel(doubleP,doubleF,doubleT);
		int sum = modelParam[0]+ modelParam[1]+ modelParam[2];
		System.out.println(Factors.toHex2Bytes(modelParam[0])+"/"+Factors.toHex2Bytes(modelParam[1])+"/"+Factors.toHex2Bytes(modelParam[2]));*/



//		CommonUtil.parseRetResult("{6B01,000300060009}");
		/*JSONObject json = new JSONObject();

		final int POWER = 1;
		final int DP = 2;

		double [] vDs = {900,605,504,301};
		double [] vTs = {32,74,86,114};

		int [] vT = Factors.getTs(vTs, vDs, POWER);
		int [] vD = Factors.getDs(vDs, vTs, POWER);

		if(vT !=null){
			System.out.println("T=t2/1E6*T^2+t1/1E3*T+t0, T's Calcution: ");
			for(int i=0; i<POWER+1; i++){
				System.out.println("t"+i+":\t"+vT[i]+"\t0x"+Factors.toHex2Bytes(vT[i]));

			}
			System.out.println("cs:\t"+Factors.checksum(vT)+"\t0x"+Factors.toHex2Bytes(Factors.checksum(vT)));
			System.out.println("T's deviation ratio is "+(float)Math.round(Factors.getTDevRatio(vTs, vDs, vT)*10000)/100+"%.");
		}

		if(vD!=null){
			System.out.println("D=d2/1E6*T^2+d1/1E3*T+d0, D's Calcution: ");
			for(int i=0; i<POWER+1; i++){
				System.out.println("d"+i+":\t"+ vD[i]+"\t0x"+Factors.toHex2Bytes(vD[i]));
			}
			System.out.println("cs:\t"+Factors.checksum(vD)+"\t0x"+Factors.toHex2Bytes(Factors.checksum(vD)));
			System.out.println("D's deviation ratio is "+(float)Math.round(Factors.getDDevRatio(vDs, vTs, vD)*10000)/100 +"%.");
		}*/


//		int[] vFt = Factors.getTs(vNs, vTs, POWER);
//		int[] vFn = Factors.getDs(vTs, vNs, POWER);

		/*int[] vFt2 = new int[vT.length];
		int[] vFn2 = new int[vD.length];

		List<String> tList = new ArrayList<>();
		String rawT = "";
		float ratioT = 0;
		if (vT != null) {
			for (int i = 0; i < POWER + 1; i++) {
				vFt2[i] = vT[i] % 65536;
				String setT = Factors.toHex2Bytes(vT[i]);
				tList.add(setT);
			}
			for (int i = 0; i < DP - POWER; i++) {
				tList.add("0000");
			}
			rawT = Factors.toHex2Bytes(Factors.checksum(vT));
			ratioT = (float)Math.round(Factors.getTDevRatio(vTs, vDs, vT) * 10000) / 100;
		}
		json.put("tList", tList);
		json.put("rawT", rawT);
		json.put("ratioT", ratioT);

		List<String> nList = new ArrayList<>();
		String rawN = "";
		float ratioN = 0;
		if (vD != null) {
			for (int i = 0; i < POWER + 1; i++) {
				vFn2[i] = vD[i] % 65536;
				String setN = Factors.toHex2Bytes(vD[i]);
				nList.add(setN);
			}
			for (int i = 0; i < DP - POWER; i++) {
				nList.add("0000");
			}
			rawN = Factors.toHex2Bytes(Factors.checksum(vD));
			ratioN = (float)Math.round(Factors.getDDevRatio(vDs, vTs, vD) * 10000) / 100;
		}

		json.put("nList", nList);
		json.put("rawN", rawN);
		json.put("ratioN", ratioN);
		json.put("status", 1);*/



//		final int POWER = 2;
//		
//		double [] vNs = {811,754,605,492,400,335};
//		double [] vTs = {51,60,77,90,96,101};
//
////		double [] vDn = {0.072289400961904,0.0541830187282786,0.0503594705685224,0.046635428372652,0.0451708883304469,0.0430062073237926,0.0346640317946034,0.0280856653875819,0.0287293509978167,0.0313341102282011,0.0268088901707559,0.023669038902964,0.0230508269106134,0.0224340827421349,0.0218206540365315,0.0218206540365315,0.0212105145892269,0.0206036384660853,0.02,0.02,0.020602276467459,0.020602276467459,0.0212013272458408,0.0217971777533941,0.0217971777533941,0.0223898531465879,0.0223898531465879,0.0229793783234105};
////		double [] vNs = {935,800,768,735,719,700,600,500,510,550,480,420,410,400,390,380,370,360,350,340,330,320,310,300,290,280,270,260};
////		double [] vTs = {28.270175,50.72,55.523072,60.268175,62.492783,65.07,77.48,87.95,86.9903,82.9575,89.8112,94.9292,95.7143,96.48,97.2263,97.9532,98.6607,99.3488,100.0175,100.6668,101.2967,101.9072,102.4983,103.07,103.6223,104.1552,104.6687,105.1628};
////		for(int i=0; i<vNs.length; i++)
////			vNs[i] = (double) Math.round(vNs[i]*(1+vDn[i]*(0.5-Math.random())*2));
//		
//		int [] vFt = Factors.getTs(vNs, vTs, POWER);
//		int [] vFn = Factors.getNs(vTs, vNs, POWER);
//		
//		int [] vFt2 = new int[vFt.length];
//		int [] vFn2 = new int[vFn.length];
//		
//		if(vFt!=null){
//			System.out.println("NTC=t2/1E4*T^2+t1/1E2*T+t0, t's Calcution: ");
//			for(int i=0; i<POWER+1; i++){
//				vFt2[i] = vFt[i] % 65536;
//				System.out.println("t"+i+":\t"+vFt[i]+"\t0x"+Factors.toHex2Bytes(vFt[i]));
////				System.out.print("-----");
////				System.out.println("t"+i+":\t"+vFt2[i]+"\t0x"+Factors.toHex2Bytes(vFt2[i]));
//
//			}
//			System.out.println("cs:\t"+Factors.checksum(vFt)+"\t0x"+Factors.toHex2Bytes(Factors.checksum(vFt)));
////			System.out.print("-----");
////			System.out.println("cs:\t"+Factors.checksum(vFt2)+"\t0x"+Factors.toHex2Bytes(Factors.checksum(vFt2)));
//			System.out.println("deviation ratio is "+(float)Math.round(Factors.getNDevRatio(vNs, vTs, vFt)*10000)/100+"%.");
//		}
//
//		if(vFn!=null){
//			System.out.println("T=n2/1E6*N^2+n1/1E3*N+n0, n's Calcution: ");
//			for(int i=0; i<POWER+1; i++){
//				vFn2[i]=vFn[i]%65536;
//				System.out.println("n"+i+":\t"+ vFn[i]+"\t0x"+Factors.toHex2Bytes(vFn[i]));
////				System.out.print("-----");
////				System.out.println("n"+i+":\t"+ vFn[i]+"\t0x"+Factors.toHex2Bytes(vFn[i]));
//			}
//			System.out.println("cs:\t"+Factors.checksum(vFn)+"\t0x"+Factors.toHex2Bytes(Factors.checksum(vFn)));
////			System.out.print("-----");
////			System.out.println("cs:\t"+Factors.checksum(vFn2)+"\t0x"+Factors.toHex2Bytes(Factors.checksum(vFn2)));
//			System.out.println("deviation ratio is "+(float)Math.round(Factors.getGDevRatio(vTs, vNs, vFn)*10000)/100 +"%.");
//		}
	}

	public static int parseDS(String ds, long userId, long deviceId) {
		if (StringUtils.isEmpty(ds)) {
			return 0;
		}
		//"049ADEF501540128002C000000000000;049ADEFF01540128002C000000000000;049ADF0701540128002C000000000000;"
		BrewedLog brewedLog = new BrewedLog();
		String[] logs = ds.split(";");
		int count = 0;
		try {
			for (String log : logs) {
				// 時間
				String time = log.substring(0, 8);
				System.out.println(parseOS(time));
				// 浸泡水溫
				String tempStr = log.substring(8, 10);
				int temp = Integer.parseInt(tempStr, 16);
				System.out.println(temp);
				// 浸泡水量
				String svlmStr = log.substring(10, 12);
				int svlm = Integer.parseInt(svlmStr, 16);
				System.out.println(svlm);
				// 浸泡時間
				String stimeStr = log.substring(12, 14);
				int stime = Integer.parseInt(stimeStr, 16);
				System.out.println(stime);
				// 衝泡量
				String vlmStr = log.substring(14, 16);
				int vlm = Integer.parseInt(vlmStr, 16);
				vlm *= 5;
				System.out.println(vlm);
				// 飲品類型
				String typeStr = log.substring(16, 18);
				int type = Integer.parseInt(typeStr, 16);
				System.out.println(type);

				System.out.println(BrewedLog.BrewType.DEVICEBREW.getValue());
//				if (brewedLog.save()) {
					count++;
//				}
			}
		} catch (NumberFormatException ne) {
			ne.printStackTrace();
		} catch (IndexOutOfBoundsException ie) {
			ie.printStackTrace();
		}
		return count;
	}

	public static Date parseOS(String os) {
		Long time = null;
		if (StringUtils.isNotEmpty(os)) {
			time = Long.parseLong(os, 16);
		}
		int startYear = 2014;

		int dayTime = (int) Math.floor(time / 100000);
		long secondTime = time % 100000;
		Date date = null;
		if (dayTime > 0 && secondTime > 0) {
			Calendar c = Calendar.getInstance();
			int year = (int) Math.floor(dayTime / 455);
			int month = (int) Math.floor((dayTime % 455) / 35);
			int day = (int) Math.floor(dayTime % 35);

			int hour = (int) Math.floor(secondTime / 3600);
			int minute = (int) Math.floor((secondTime % 3600) / 60);
			int second = (int) Math.floor(secondTime % 60);

			c.set(startYear + year, month - 1, day, hour, minute, second);
			date = c.getTime();
		}
		return date;
	}
}
